/*
 * MinimumChooser.hpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MINIMUMCHOOSER_HPP_
#define MINIMUMCHOOSER_HPP_

#include "bfr/CoefficientType.hpp"

#include "bfr/lpbCombinatorial/TreeContext.hpp"
#include "bfr/lpbCombinatorial/SolverInformation.hpp"
#include "bfr/lpbCombinatorial/CoefficientSelectionException.hpp"

namespace bfr {

class MinimumChooser {
    public:
        MinimumChooser() { }

        ~MinimumChooser() { }

        lpb_coefficient_t chooseCoefficient(lpb_coefficient_t a,
                                              lpb_coefficient_t b,
                                              TreeContext *tree,
                                              SolverInformation &information,
                                              size_t k)
            const throw(CoefficientSelectionException) {
            if ((a >= b) || (a == coeff_pos_infinity) || (b == coeff_neg_infinity)) {
                throw CoefficientSelectionException(a, b);
            }
            if (a == coeff_neg_infinity) {
                if (b == coeff_pos_infinity) {
                    return 0;
                }
                else {
                    // TODO what if b is 0?
                    // a is infinity and b a number
                    if (b == 0)
                        throw CoefficientSelectionException(a, b);
                    return b - 1;
                }
            }
            else {
                // a must be a number
                if (b == coeff_pos_infinity) {
		  return floor(a + 1);//JGS
                }
                else {
                    // both are numbers
		  lpb_coefficient_t smallestSol = floor(a + 1);//JGS
                    if (!(smallestSol < b)) {
                        throw CoefficientSelectionException(a, b);
                    }
                    else {
                        return smallestSol;
                    }
                }
            }
        }
};

}

#endif  // MINIMUMCHOOSER_HPP_
